﻿using System.Net;
using System.Text;
using System.Web.Hosting;
using System.Threading;
namespace System.Web
{
    public partial class NetHttpRuntime
    {
        private static NetHttpWorkerRequest.EndOfSendNotification _asyncEndOfSendCallback = null;
        private static AsyncCallback _handlerCompletionCallback = null;

        internal static void ProcessRequestNow(WebHost host, WebHostWorkerRequest wr, NetHttpApplicationFactory applicationFactory)
        {
            wr.ResetStartTime();
            NetHttpContext context;
            try { context = new NetHttpContext(wr); }
            catch
            {
                wr.SendStatus(400, "Bad Request");
                wr.SendKnownResponseHeader(12, "text/html; charset=utf-8");
                var bytes = Encoding.ASCII.GetBytes("<html><body>Bad Request</body></html>");
                wr.SendResponseFromMemory(bytes, bytes.Length);
                wr.FlushResponse(true);
                wr.EndOfRequest();
                return;
            }
            Console.WriteLine("a:Request");
            wr.SetEndOfSendNotification(_asyncEndOfSendCallback, context);
            Interlocked.Increment(ref host._activeRequests);
            NetHttpApplication application = null;
            try
            {
                try { EnsureFirstRequestInit(context); }
                catch
                {
                    if (!((NetHttpRequest)context.Request).IsDebuggingRequest)
                        throw;
                }
                ((NetHttpResponse)context.Response).InitResponseWriter();
                application = applicationFactory.GetApplicationInstance(wr, context);
                if (application == null)
                    throw new HttpException("Unable_create_app_object");
                if (application is INetHttpAsyncHandler)
                {
                    var handler2 = (INetHttpAsyncHandler)application;
                    context.AsyncAppHandler = handler2;
                    handler2.BeginProcessRequest(context, _handlerCompletionCallback, context);
                }
                else
                {
                    ((INetHttpHandler)application).ProcessRequest(context);
                    FinishRequest(host, context.WorkerRequest, context, null);
                }
            }
            catch (Exception ex)
            {
                ((NetHttpResponse)context.Response).InitResponseWriter();
                FinishRequest(host, wr, context, ex);
            }
            finally
            {
                if (application != null)
                    applicationFactory.RecycleApplicationInstance(application);
            }
        }

        internal static void RejectRequestNow(WebHost host, WebHostWorkerRequest wr, bool silent)
        {
            var context = new NetHttpContext(wr, false);
            wr.SetEndOfSendNotification(_asyncEndOfSendCallback, context);
            Console.WriteLine("a:Request");
            Interlocked.Increment(ref host._activeRequests);
            if (silent)
            {
                ((NetHttpResponse)context.Response).InitResponseWriter();
                FinishRequest(host, wr, context, null);
            }
            else
            {
                try { throw new HttpException(0x1f7, "Server_too_busy"); }
                catch (Exception ex)
                {
                    ((NetHttpResponse)context.Response).InitResponseWriter();
                    FinishRequest(host, wr, context, ex);
                }
            }
        }

        private static void FinishRequest(WebHost host, NetHttpWorkerRequest wr, NetHttpContext context, Exception e)
        {
            var response = (NetHttpResponse)context.Response;
            if (e == null)
            {
                try { response.FinalFlushAtTheEndOfRequestProcessing(); }
                catch (Exception e2) { e = e2; }
            }
            if (e != null)
            {
                context.DisableCustomHttpEncoder = true;
                try
                {
                    try { response.ReportRuntimeError(e, true, false); }
                    catch (Exception e2) { response.ReportRuntimeError(e2, false, false); }
                    response.FinalFlushAtTheEndOfRequestProcessing();
                }
                catch { }
            }
            _firstRequestCompleted = true;
            int statusCode = response.StatusCode;
            //context.FinishRequestForCachedPathData(statusCode);
            try { wr.EndOfRequest(); }
            catch (Exception e3) { RaiseRuntimeError(e3, wr); }
            Console.WriteLine("d:Request");
            Interlocked.Decrement(ref host._activeRequests);
            if (WebHost.UseThreading)
                if (host._requestQueue != null)
                    host._requestQueue.ScheduleMoreWorkIfNeeded();
        }

        //private RequestNotificationStatus ProcessRequestNotification(WebHostWorkerRequest wr, NetHttpContext context, NetHttpApplicationFactory applicationFactory)
        //{
        //    var pending = RequestNotificationStatus.Pending;
        //    try
        //    {
        //        int num;
        //        bool flag;
        //        int num2;
        //        UnsafeIISMethods.MgdGetCurrentNotificationInfo(wr.RequestContext, out num, out flag, out num2);
        //        context.CurrentModuleIndex = num;
        //        context.IsPostNotification = flag;
        //        context.CurrentNotification = (RequestNotification)num2;
        //        INetHttpHandler applicationInstance = null;
        //        if (context.NeedToInitializeApp())
        //        {
        //            try { EnsureFirstRequestInit(context); }
        //            catch
        //            {
        //                if (!((NetHttpRequest)context.Request).IsDebuggingRequest)
        //                    throw;
        //            }
        //            ((NetHttpResponse)context.Response).InitResponseWriter();
        //            applicationInstance = applicationFactory.GetApplicationInstance(context);
        //            if (applicationInstance == null)
        //                throw new HttpException("Unable_create_app_object");
        //            var application = (applicationInstance as NetHttpApplication);
        //            if (application != null)
        //                application.AssignContext(context);
        //        }
        //        wr.SynchronizeVariables(context);
        //        if (context.ApplicationInstance != null)
        //        {
        //            if (context.ApplicationInstance.BeginProcessRequestNotification(context, _requestNotificationCompletionCallback).CompletedSynchronously)
        //                pending = RequestNotificationStatus.Continue;
        //        }
        //        else if (applicationInstance != null)
        //        {
        //            applicationInstance.ProcessRequest(context);
        //            pending = RequestNotificationStatus.FinishRequest;
        //        }
        //        else
        //            pending = RequestNotificationStatus.Continue;
        //    }
        //    catch (Exception exception)
        //    {
        //        pending = RequestNotificationStatus.FinishRequest;
        //        ((NetHttpResponse)context.Response).InitResponseWriter();
        //        context.AddError(exception);
        //    }
        //    if (pending != RequestNotificationStatus.Pending)
        //        FinishRequestNotification(wr, context, ref pending);
        //    return pending;
        //}
    }
}
